package com.ap.core.jbehave.retrievertp;

import static org.hamcrest.MatcherAssert.assertThat;

import org.hamcrest.CoreMatchers;
import org.jbehave.core.annotations.Given;
import org.jbehave.core.annotations.Then;
import org.jbehave.core.annotations.When;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ap.core.cxf.jaxb.common.DeliveryType;
import com.ap.core.cxf.jaxb.managepayment.RTPSummaryType;
import com.ap.core.cxf.jaxb.managepayment.RetrieveRTP1Request;
import com.ap.core.cxf.jaxb.managepayment.RetrieveRTP1Response;
import com.ap.core.cxf.jaxb.managertp.SubmitRTP1Request;
import com.ap.core.cxf.jaxb.managertp.SubmitRTP1Response;
import com.ap.core.cxf.jaxb.managertp.SubmitRTPMessageType;
import com.ap.core.cxf.jaxb.rtp.RTPSenderInfoType;
import com.ap.core.cxf.jaxb.rtp.TransactionCheckOutType;
import com.ap.core.jbehave.BaseTransitionRTPSteps;
import com.ap.core.jbehave.StoryContext;
import com.ap.core.util.JaxbUtil;
import com.ap.core.util.Nullable;
import com.ap.core.util.TypedKey;
import com.core.ap.wsdl.managepaymentservice_1.ManagePayment1PortType;
import com.core.ap.wsdl.managepaymentservice_1.RetrieveRTP1Fault;
import com.core.ap.wsdl.managertpservice_1.ManageRTP1PortType;
import com.core.ap.wsdl.managertpservice_1.SubmitRTP1Fault;

public class RetrieveRTPMobDeliverySteps extends BaseTransitionRTPSteps {

	private static final TypedKey<RTPSummaryType> RTP_SUMMARY = new TypedKey<>(
			"RTP Summary");
	private static final TypedKey<RTPSenderInfoType> RTP_SENDER_INFO = new TypedKey<>(
			"RTP Sender Info");
	// public static final TypedKey<DistributorInfoType> DISTRIBUTOR_INFO_TYPE =
	// new TypedKey<>("Distributor Info Type");
	private static final TypedKey<String> RTP_MSGTYPE = new TypedKey<>(
			"RTP Message Type");
	private static final Logger LOG = LoggerFactory
			.getLogger(RetrieveRTPSteps.class);
	private String apTransactionId = null;
	private static final TypedKey<RetrieveRTP1Request> REQUEST = new TypedKey<>(
			"REQUEST");
	private static final TypedKey<RetrieveRTP1Response> RESPONSE = new TypedKey<>(
			"RESPONSE");
	private static final TypedKey<SubmitRTP1Request> SUBMITRTP_REQUEST = new TypedKey<>(
			"REQUEST");

	private SubmitRTP1Response responseRTPType;
	/**
	 * 
	 * @param storyContext
	 */
	public RetrieveRTPMobDeliverySteps(StoryContext storyContext) {
		super(storyContext);
	}

	@Given("Distributor has been registered correctly")
	public void givenValidRequestSubmitted() throws SubmitRTP1Fault {
		LOG.info("Given - Distributor has been registered correctly");

		final ManageRTP1PortType singnedPort = factory
				.getBean(ManageRTP1PortType.class);
		SubmitRTP1Request submitRTPRequest = createSubmitRTPRequest(SubmitRTPMessageType.SUBMITRTPFORMOB);
		submitRTPRequest.getRTPSummary().setTxCheckout(
				TransactionCheckOutType.NRMLCHK);

		submitRTPRequest.getRTPSenderInfo().getDistributorInfo()
				.setDistributorId("000001");
		submitRTPRequest.getRTPSenderInfo().getDetailMerchantInfo()
				.getMerchantInfo().setMerchantId("000001");
		submitRTPRequest.getDelivery().setDeliveryType(DeliveryType.COLLST);

		LOG.info("When -  a Consumer chooses to make payment using AP service through m-com site to purchase a digital product");
		JaxbUtil.newInstance().javaToXML(SubmitRTP1Request.class,
				submitRTPRequest);

		responseRTPType = singnedPort
				.submitRTP1(submitRTPRequest);
		apTransactionId = responseRTPType.getResponseInfo()
				.getApTransactionId();
		storyContext.put(SUBMITRTP_REQUEST, submitRTPRequest);
	}

	@Given("FI App has been launched by the merchant site")
	public void givenFIAppLaunched() {
		LOG.info("Given - FI App has been launched by the merchant site");
	}

	@Given("the consumer has been authenticated")
	public void givenConsumerAuthenticated() {
		LOG.info("Given - FI the consumer has been authenticated");
	}

	@When("Consumer's FI sends the request to Retrieve previously submitted RTP to AP Server")
	public void whenAPCoreReceivedValidRETRIEVERTP() throws RetrieveRTP1Fault {
		LOG.info("When -  Consumer's FI sends the request to Retrieve previously submitted RTP to AP Server");

		final ManagePayment1PortType singnedPort = factory
				.getBean(ManagePayment1PortType.class);
		RetrieveRTP1Request retrieveRTPRequest = createRetrieveRTPRequest();
		
		 if(null == responseRTPType.getResponseInfo().getBRN()){
			 retrieveRTPRequest.getRequestInfo().setApTransactionId(responseRTPType.getResponseInfo().getApTransactionId());
			 retrieveRTPRequest.getRequestInfo().setApTRId(responseRTPType.getResponseInfo().getApTRId());
			 retrieveRTPRequest.getRequestInfo().setBRN(null); 
	        }else{
	        	retrieveRTPRequest.getRequestInfo().setApTransactionId(null);
	        	retrieveRTPRequest.getRequestInfo().setApTRId(null);
	        	retrieveRTPRequest.getRequestInfo().setBRN(responseRTPType.getResponseInfo().getBRN());            
	        }
		
		retrieveRTPRequest.getRequestInfo().setApTransactionId(apTransactionId);
		retrieveRTPRequest.getRequestInfo().setFIId("000002");
		retrieveRTPRequest.getRequestInfo().setFIConsumerId("hsbccon2");
		JaxbUtil.newInstance().javaToXML(RetrieveRTP1Request.class,
				retrieveRTPRequest);
		RetrieveRTP1Response retrieveRTPResponse = singnedPort
				.retrieveRTP1(retrieveRTPRequest);
		LOG.info("When -  Response Received");
		JaxbUtil.newInstance().javaToXML(RetrieveRTP1Response.class,
				retrieveRTPResponse);

		storyContext.put(REQUEST, retrieveRTPRequest);
		storyContext.put(RESPONSE, retrieveRTPResponse);
		storyContext.put(RTP_SUMMARY, retrieveRTPResponse.getRTPSummary());
		storyContext.put(RTP_SENDER_INFO,
				retrieveRTPResponse.getRTPSenderInfo());
	}

	@Then("AP Server should respond with the RTP which will be displayed on Consumer FI app")
	public void thenRTPFORAUTHtoOSB() {

		LOG.info("Then -  AP Server should respond with the RTP which will be displayed on Consumer FI app");

		Nullable<SubmitRTP1Request> submitRTPRequest = Nullable
				.nullable(storyContext.get(SUBMITRTP_REQUEST));
		Nullable<RetrieveRTP1Request> retrieveRTPRequest = Nullable
				.nullable(storyContext.get(REQUEST));
		Nullable<RetrieveRTP1Response> retrieveRTPResponse = Nullable
				.nullable(storyContext.get(RESPONSE));

		String MsgId = retrieveRTPRequest.value().getMsgHdr().getMsgId();
		String orgReqMsgId = retrieveRTPResponse.value().getMsgHdr()
				.getOrgReqMsgId();
		String reqFIId = retrieveRTPRequest.value().getRequestInfo()
				.getFIId();
		String conFIId = retrieveRTPResponse.value().getConsumerInfo()
				.getFIId();
		String reqbankConsumerID = retrieveRTPRequest.value().getRequestInfo()
				.getFIConsumerId();
		String resbankConsumerID = retrieveRTPResponse.value()
				.getConsumerInfo().getFIConsumerId();

		doRetrieveRTPResponseAssertions(
				Nullable.nullable(storyContext.get(RTP_SUMMARY)),
				Nullable.nullable(storyContext.get(RTP_SENDER_INFO)),
				Nullable.nullable(storyContext.get(RTP_MSGTYPE)));

		assertThat("OrgReqMsgId is not matching with MsgId", MsgId,
				CoreMatchers.equalTo(orgReqMsgId));

		assertThat("Consumer FIId is not matching with RequestInfoFIlId",
				reqFIId, CoreMatchers.equalTo(conFIId));

		assertThat(
				"Consumer FIConsumerId is not matching with RequestInfoFIConsumerId",
				reqbankConsumerID, CoreMatchers.equalTo(resbankConsumerID));

		assertThat(
				"SubmitRTP Request DeliveryType is not matching with Retrieve RTP Response DeliveryType",
				submitRTPRequest.value().getDelivery().getDeliveryType(),
				CoreMatchers.equalTo(retrieveRTPResponse.value().getDelivery()
						.getDeliveryType()));

		assertThat(
				"SubmitRTP Request TransactionType is not matching with Retrieve RTP Response TransactionType",
				submitRTPRequest.value().getRTPSummary().getTxType(),
				CoreMatchers.equalTo(retrieveRTPResponse.value()
						.getRTPSummary().getTxType()));

		assertThat(
				"SubmitRTP Request TransactionCheckOutType is not matching with Retrieve RTP Response TransactionCheckOutType",
				submitRTPRequest.value().getRTPSummary().getTxCheckout(),
				CoreMatchers.equalTo(retrieveRTPResponse.value()
						.getRTPSummary().getTxCheckout()));

		assertThat(
				"SubmitRTP Request DeliveryAddressLine1 is not matching with Retrieve RTP Response DeliveryAddressLine1",
				submitRTPRequest.value().getDelivery().getDeliveryAddress()
						.getAddressLine1(),
				CoreMatchers.equalTo(retrieveRTPResponse.value().getDelivery()
						.getDeliveryAddress().getAddressLine1()));

		assertThat(
				"SubmitRTP Request DeliveryAddressLine2 is not matching with Retrieve RTP Response DeliveryAddressLine2",
				submitRTPRequest.value().getDelivery().getDeliveryAddress()
						.getAddressLine2(),
				CoreMatchers.equalTo(retrieveRTPResponse.value().getDelivery()
						.getDeliveryAddress().getAddressLine2()));

		assertThat(
				"SubmitRTP Request Delivery Postcode is not matching with Retrieve RTP Response Delivery Postcode",
				submitRTPRequest.value().getDelivery().getDeliveryAddress()
						.getPostCode(),
				CoreMatchers.equalTo(retrieveRTPResponse.value().getDelivery()
						.getDeliveryAddress().getPostCode()));

		assertThat(
				"SubmitRTP Request Delivery Countrycode is not matching with Retrieve RTP Response Delivery Countrycode",
				submitRTPRequest.value().getDelivery().getDeliveryAddress()
						.getCountryCode(),
				CoreMatchers.equalTo(retrieveRTPResponse.value().getDelivery()
						.getDeliveryAddress().getCountryCode()));

		LOG.info("Test executed successfully...");
	}

}
